package entity;

import NLP.GrammarCheck;
import NLP.impl.GrammarCheckImpl;
import ga.AssociationDegree;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author: ChenforCode
 * @date: 2018/12/29 19:30
 * @description: 染色体
 */
public class Chromosome {
    private List<Word> gene;
    private double fitness;

    public Chromosome(List<Word> gene, double fitness) {
        this.gene = gene;
        this.fitness = fitness;
    }

    public Chromosome() {
    }

    public List<Word> getGene() {
        return gene;
    }

    public void setGene(List<Word> gene) {
        this.gene = gene;
    }

    public double getFitness() {
        return fitness;
    }

    public void setFitness(double fitness) {
        this.fitness = fitness;
    }

    /**
     * @return void
     * @Author ChenforCode
     * @Description //TODO 计算自己的适应度
     * @Date 19:35 2018/12/29
     * @Param []
     **/
    public void calcFitness(Word themeWord) {
        GrammarCheck gCheck = new GrammarCheckImpl();
        //fit1: 满足语法 fit2：与主题相关度之和 fit3: 连续词语相关度之和 fit4: 感情统一
        double fit1 = 0, fit2 = 0, fit3 = 0, fit4 = 0;
        int index = 0;
        Word[] words = new Word[gene.size()];
        //1、语法检查
        if (gCheck.checkGrammar(gene)) {
            fit1 = 1;
        }

        //2、计算与主题相关度
        Iterator it = gene.iterator();
        while (it.hasNext()) {
            Word tempWord = (Word) it.next();
            words[index++] = tempWord;
            fit2 += AssociationDegree.getAssociationDegree(tempWord, themeWord);
        }

        //3、计算相连词语的相关度之和
        for (int i = 0; i < gene.size() - 1; i++) {
            fit3 += AssociationDegree.getAssociationDegree(words[i], words[i + 1]);
        }

        //4、情感统一
        double posSum = 0;
        double posAvg = 0;
        double[] emotions = new double[gene.size()];
        for (int i = 0; i < gene.size(); i++) {
            emotions[i] = words[i].getSentiment().getPos();
            posSum += emotions[i];
        }
        posAvg = posSum / emotions.length;
        double fenzi = 0;
        for (int i = 0; i < emotions.length; i++){
            fenzi += (Math.pow(emotions[i] - posAvg, 2));
        }
        fit4 = fenzi / emotions.length;

        fitness = fit1 * 10 + fit2 + fit3 + (1/fit4)/10;
    }

    @Override
    public String toString() {
        return "Chromosome{" +
                "gene=" + gene +
                ", fitness=" + fitness +
                '}';
    }
}
